package com.yantong.utils;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期处理
 * @author kanghaixin
 */
public class DateUtils {
    private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);
    /**
     * 时间格式(yyyy-MM-dd)
     */
    public final static String DATE_PATTERN = "yyyy-MM-dd";
    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";


    public static String formatFull(Date date) {
        if (date == null) {
            return "";
        }
        return format(date, DATE_TIME_PATTERN);
    }

    public static String format(Date date) {
        if (date == null) {
            return "";
        }
        return format(date, DATE_PATTERN);
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 计算距离现在多久，非精确
     *
     * @param date
     * @return
     */
    public static String getTimeBefore(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        } else if (hour > 0) {
            r += hour + "小时";
        } else if (min > 0) {
            r += min + "分";
        } else if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }

    /**
     * 计算距离现在多久，精确
     *
     * @param date
     * @return
     */
    public static String getTimeBeforeAccurate(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        }
        if (hour > 0) {
            r += hour + "小时";
        }
        if (min > 0) {
            r += min + "分";
        }
        if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }


    public static Date parseDate(String s, String pattern) {
        if (s == null || s.length() == 0) {
            return null;
        }
        try {
            return new SimpleDateFormat(pattern).parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date parseDate(String s) {
        if (s == null || s.length() == 0) {
            return null;
        }
        try {
            return new SimpleDateFormat(DATE_PATTERN).parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static Date parseDateForm(String s) {
        if (s == null || s.length() == 0) {
            return null;
        }
        try {
            return new SimpleDateFormat(DATE_TIME_PATTERN).parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Integer hoursBetween(Date source, Date dest) {
        Calendar first = Calendar.getInstance();
        first.setTime(source);
        Calendar second = Calendar.getInstance();
        second.setTime(dest);
        return (int) Math.abs((first.getTime().getTime() - second.getTime().getTime()) / 1000 / 3600);
    }

    public static int daysBetween(Date start, Date end) {
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();

        calendar1.setTime(start);
        calendar2.setTime(end);

        int days = calendar2.get(Calendar.DAY_OF_YEAR) - calendar1.get(Calendar.DAY_OF_YEAR);
        return days;
    }

    public static double monthBetween(Date start, Date end) {
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();

        calendar1.setTime(start);
        calendar2.setTime(end);

        int year = calendar2.get(Calendar.YEAR) - calendar1.get(Calendar.YEAR);
        int month = calendar2.get(Calendar.MONTH) - calendar1.get(Calendar.MONTH);
        month = year * 12 + month;

        int days = 0;
        int d1 = calendar1.get(Calendar.DAY_OF_MONTH);
        int d2 = calendar2.get(Calendar.DAY_OF_MONTH);
        if (month == 0) {
            if (d1 == calendar1.getActualMinimum(Calendar.DAY_OF_MONTH) && d2 == calendar2.getActualMaximum(Calendar.DAY_OF_MONTH)) {
                month = 1;
            } else if (d1 == calendar1.getActualMaximum(Calendar.DAY_OF_MONTH) && d2 == calendar2.getActualMinimum(Calendar.DAY_OF_MONTH)) {
                month = -1;
            } else {
                if (d2 > d1) {
                    days = d2 - d1 + 1;
                } else {
                    days = -(d2 - d1 + 1);
                }
            }

        } else {
            if (month > 0) {
                if (d1 > d2) {
                    month = month - 1;
                    days = calendar2.get(Calendar.DAY_OF_MONTH) + (30 - calendar1.get(Calendar.DAY_OF_MONTH)) + 1;
                } else {
                    if (d1 == calendar1.getActualMinimum(Calendar.DAY_OF_MONTH) && d2 == calendar2.getActualMaximum(Calendar.DAY_OF_MONTH)) {
                        month = month + 1;
                    }else {
                        days = d2 - d1 + 1;
                    }
                }
            } else {
                if (d1 > d2) {
                    days = d2 - d1 - 1;
                } else {
                    month = month + 1;
                    days = -(calendar1.get(Calendar.DAY_OF_MONTH) + 30 - calendar2.get(Calendar.DAY_OF_MONTH) + 1);
                }
            }
        }
        double result = (double) days / 30;
        BigDecimal bg = new BigDecimal(month + result).setScale(2, RoundingMode.HALF_UP);
        return bg.doubleValue();
    }
    
    /**
     * 将String格式时间转换成Long(单位:秒) 
     * @author 宋立明
     * @date 2018年8月29日 下午5:02:21
     * @param formatDate
     * @return
     */
    public static Integer getDateLong(String formatDate){
        if(StringUtils.isEmpty(formatDate)){
            return null;
        }
        SimpleDateFormat sdf = null;
        if(formatDate != null && formatDate.length() < 11) {
            sdf = new SimpleDateFormat("yyyy-MM-dd");
        }else{
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
        try{
            Date d = sdf.parse(formatDate);
            Long lo = d.getTime()/1000;
            return Integer.parseInt(lo+"");
        }catch(Exception e){
            logger.error("格式转换失败, error Massage:{}", e.getMessage());
        }
        return null;
    }
    
    /**
     * 将Long型秒转换成 yyyy-MM-dd HH:mm:ss时间格式
     * @author 宋立明
     * @date 2018年8月29日 下午8:00:59
     * @param formatDate
     * @return
     */
    public static String getDateFormat(Integer formatDate){
        if(formatDate!=null){
            Long lo = Long.parseLong(formatDate+"") * 1000;
            Date date = new Date(lo);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.format(date);
        }else{
            return "";
        }
    }
    
    public static Date getSleepDateFormat(Date formatDate){
        try{
            if(formatDate!=null){
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String str = sdf.format(formatDate);
                SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = sdf2.parse(str+" 20:00:00");
                return date;
            }else{
                return null;
            }
        }catch (ParseException e){
            logger.error("时间转换出错, e:{}", e.getMessage());
            return null;
        }
    }


    /**
     * 加小时后的日期时间
     * @param date
     * @return
     */
    public static Date getAddHourDate(Date date,int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        return calendar.getTime();
    }

    /**
     * 加天数后的日期
     * @param date
     * @param days
     * @return
     */
    public static Date getAddDayDate(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        return calendar.getTime();
    }

    /**
     * 加月份后的日期
     * @param date
     * @param month
     * @return
     */
    public static Date getAddMonthDate(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }

    /**
     * 加年份后的日期
     * @param date
     * @return
     */
    public static Date getAddYearDate(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 获取某天的开始时间
     * @param date
     * @return
     */
    public static Date getDateStartTime(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE,0);
        cal.set(Calendar.SECOND,0);
        cal.set(Calendar.MILLISECOND,0);
        return cal.getTime();
    }


    /**
     * 获取上月开始时间
     * @return
     */
    public static Date getPreMonthStart() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MILLISECOND,0);
        return calendar.getTime();
    }

    /**
     * 获取上月结束时间
     * @return
     */
    public static Date getPreMonthEnd() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE,59);
        calendar.set(Calendar.SECOND,59);
        calendar.set(Calendar.MILLISECOND,999);
        return calendar.getTime();
    }

    /**
     * 获取当月开始时间
     * @return
     */
    public static Date getMonthStart() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH,1);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MILLISECOND,0);
        return calendar.getTime();
    }

    /**
     * 获取当月结束时间
     * @return
     */
    public static Date getMonthEnd() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE,59);
        calendar.set(Calendar.SECOND,59);
        calendar.set(Calendar.MILLISECOND,999);
        return calendar.getTime();
    }
    /**
     * 获取指定时间
     * @param date
     * @param hour
     * @param minute
     * @return
     */
    public static Date getAppointTime(Date date, int hour, int minute) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE,minute);
        cal.set(Calendar.SECOND,0);
        cal.set(Calendar.MILLISECOND,0);
        return cal.getTime();
    }

    /**
     * 获取某天的结束时间
     * @param date
     * @return
     */
    public static Date getDateEndTime(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE,59);
        cal.set(Calendar.SECOND,59);
        cal.set(Calendar.MILLISECOND,999);
        return cal.getTime();
    }

    /**
     * 获取本周第一天，当前时间，起始从周日
     * @return
     */
    public static Date getWeekFirstDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_WEEK,1);
        return calendar.getTime();
    }

    //计算与当前时间相隔多少天
    public static Integer longOfTwoDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN);
        Date begin = null;
        Date end = null;
        try {
            begin = sdf.parse(sdf.format(new Date()));
            end = sdf.parse(sdf.format(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Long betweenDate = (end.getTime() - begin.getTime())/(1000*60*60*24);
        return betweenDate.intValue();
    }


    public static void main(String[] args) throws ParseException {
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//
//        System.out.println(format.format(getAddHourDate(new Date(), -24)));
//        System.out.println(format.format(getDateEndTime(getAddDayDate(new Date(), -7))));
//
//
//        System.out.println(format.format(DateUtils.getAppointTime(DateUtils.getAddDayDate(DateUtils.getAddMonthDate(getMonthStart(),-1), -1), 20, 30)));
//        System.out.println(format.format( DateUtils.getAppointTime(DateUtils.getAddDayDate(DateUtils.getMonthStart(),-1), 20, 0)));
//        System.out.println(format.format(getWeekFirstDay()));
//
//        System.out.println(format.format(getPreMonthStart()));
//        System.out.println(format.format(getPreMonthEnd()));
        String first = "2020-07-29";
        String second = "2020-07-31";


        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = format.parse(second);
        Integer days = longOfTwoDate(date);
        System.out.println(days);
    }

}
